package com.abel.bigwater.dataserver.model.kming

import com.abel.bigwater.data.BcdString
import com.alibaba.fastjson.JSON
import io.netty.buffer.Unpooled
import org.joda.time.DateTime
import org.junit.Assert.*
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runners.MethodSorters
import org.slf4j.LoggerFactory

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class KmingPacketPerformTest {
    @Test
    fun test11LongData() {

        val p1 = KmingPacket().apply {
            termCode.size = SizeType.Horizon100
            termCode.remote = RemoteType.PulseRemote
            termCode.codeBcd = BcdString.fromBcdString("05 06 07 08")

            deviceStatus.lowVoltMeter20 = true
            limitStatus.upperLimitWarn20 = true

            sessionStatus.serialNo = 102

            data = TermSendData().also {
                it.startTime = DateTime(2018, 4, 5, 6, 7, 8).toDate()
                it.sampleSeconds = 600
                it.channelCount = 1
                it.dataCount = 144

                val kcd = KmingChannelData(KmingChannelType.MeterNetInt, ArrayList(144), null)
                for (i in 1..144) {
                    kcd.dataList.add(10000 + i)
                }

                it.channelDataList.add(kcd)
            }
            dataLen = data!!.bufLength()
        }

        val buf = Unpooled.buffer()
        p1.pack(buf)

        lgr.info("packet with send-data: {}", BcdString.hexString(buf, withBlank = true))
        assertArrayEquals(BcdString.toByteArray(PLAIN_LONG_TEXT),
                ByteArray(buf.readableBytes()).also { buf.readBytes(it) })
    }

    @Test
    fun test12LongDataSecret() {

        val p1 = KmingPacket().apply {
            termCode.size = SizeType.Horizon100
            termCode.remote = RemoteType.PulseRemote
            termCode.codeBcd = BcdString.fromBcdString("05 06 07 08")

            deviceStatus.lowVoltMeter20 = true
            limitStatus.upperLimitWarn20 = true

            sessionStatus.encrypted = true
            sessionStatus.serialNo = 102

            data = TermSendData().also {
                it.startTime = DateTime(2018, 4, 5, 6, 7, 8).toDate()
                it.sampleSeconds = 600
                it.channelCount = 1
                it.dataCount = 144

                val kcd = KmingChannelData(KmingChannelType.MeterNetInt, ArrayList(144), null)
                for (i in 1..144) {
                    kcd.dataList.add(10000 + i)
                }

                it.channelDataList.add(kcd)
            }
            dataLen = data!!.bufLength()
        }

        val buf = Unpooled.buffer()
        p1.pack(buf)

        lgr.info("packet with send-data: {}", BcdString.hexString(buf, withBlank = true))
        assertArrayEquals(BcdString.toByteArray(SECRET_LONG_TEXT),
                ByteArray(buf.readableBytes()).also { buf.readBytes(it) })
    }

    @Test
    fun test13LongDataParsing() {
        val buf = Unpooled.buffer().writeBytes(BcdString.toByteArray(PLAIN_LONG_TEXT))

        val plst = KmingPacket.parseLongPacket(buf)
        assertEquals(1, plst.size)

        val data = plst[0].data as TermSendData
        assertEquals(10001, data.channelDataList[0].dataList.first())
        assertEquals(10144, data.channelDataList[0].dataList.last())

        lgr.info("long packet: {}", JSON.toJSONString(plst, true))
    }

    @Test
    fun test14LongDataParsingSecret() {
        val buf = Unpooled.buffer().writeBytes(BcdString.toByteArray(SECRET_LONG_TEXT))

        val plst = KmingPacket.parseLongPacket(buf)
        assertEquals(1, plst.size)

        val data = plst[0].data as TermSendData
        assertEquals(10001, data.channelDataList[0].dataList.first())
        assertEquals(10144, data.channelDataList[0].dataList.last())

        lgr.info("long packet: {}", JSON.toJSONString(plst, true))
    }

    @Test
    fun test21LongDataNoSplit() {

        val p1 = KmingPacket().apply {
            termCode.size = SizeType.Horizon100
            termCode.remote = RemoteType.PulseRemote
            termCode.codeBcd = BcdString.fromBcdString("05 06 07 08")

            deviceStatus.lowVoltMeter20 = true
            limitStatus.upperLimitWarn20 = true

            sessionStatus.serialNo = 102

            splitPacket = false

            data = TermSendData().also {
                it.startTime = DateTime(2018, 4, 5, 6, 7, 8).toDate()
                it.sampleSeconds = 600
                it.channelCount = 1
                it.dataCount = 144

                val kcd = KmingChannelData(KmingChannelType.MeterNetInt, ArrayList(144), null)
                for (i in 1..144) {
                    kcd.dataList.add(10000 + i)
                }

                it.channelDataList.add(kcd)
            }
            dataLen = data!!.bufLength()
        }

        val buf = Unpooled.buffer()
        p1.pack(buf)

        lgr.info("packet with send-data: {}", BcdString.hexString(buf, withBlank = true))
        assertArrayEquals(BcdString.toByteArray(PLAIN_LONG_NO_SPLIT),
                ByteArray(buf.readableBytes()).also { buf.readBytes(it) })
    }

    @Test
    fun test22LongDataSecretNoSplit() {

        val p1 = KmingPacket().apply {
            termCode.size = SizeType.Horizon100
            termCode.remote = RemoteType.PulseRemote
            termCode.codeBcd = BcdString.fromBcdString("05 06 07 08")

            deviceStatus.lowVoltMeter20 = true
            limitStatus.upperLimitWarn20 = true

            sessionStatus.encrypted = true
            sessionStatus.serialNo = 102

            splitPacket = false

            data = TermSendData().also {
                it.startTime = DateTime(2018, 4, 5, 6, 7, 8).toDate()
                it.sampleSeconds = 600
                it.channelCount = 1
                it.dataCount = 144

                val kcd = KmingChannelData(KmingChannelType.MeterNetInt, ArrayList(144), null)
                for (i in 1..144) {
                    kcd.dataList.add(10000 + i)
                }

                it.channelDataList.add(kcd)
            }
            dataLen = data!!.bufLength()
        }

        val buf = Unpooled.buffer()
        p1.pack(buf)

        lgr.info("packet with send-data: {}", BcdString.hexString(buf, withBlank = true))
        assertArrayEquals(BcdString.toByteArray(SECRET_LONG_NO_SPLIT),
                ByteArray(buf.readableBytes()).also { buf.readBytes(it) })
    }

    @Test
    fun test23LongDataParsingNoSplit() {
        val buf = Unpooled.buffer().writeBytes(BcdString.toByteArray(PLAIN_LONG_NO_SPLIT))

        val plst = KmingPacket.parseLongPacket(buf)
        assertEquals(1, plst.size)

        val data = plst[0].data as TermSendData
        assertEquals(10001, data.channelDataList[0].dataList.first())
        assertEquals(10144, data.channelDataList[0].dataList.last())

        lgr.info("long packet: {}", JSON.toJSONString(plst, true))
    }

    @Test
    fun test24LongDataParsingSecretNoSplit() {
        val buf = Unpooled.buffer().writeBytes(BcdString.toByteArray(SECRET_LONG_NO_SPLIT))

        val plst = KmingPacket.parseLongPacket(buf)
        assertEquals(1, plst.size)

        val data = plst[0].data as TermSendData
        assertEquals(10001, data.channelDataList[0].dataList.first())
        assertEquals(10144, data.channelDataList[0].dataList.last())

        lgr.info("long packet: {}", JSON.toJSONString(plst, true))
    }

    companion object {
        private val lgr = LoggerFactory.getLogger(KmingPacketPerformTest::class.java)

        const val PLAIN_LONG_TEXT = """
aa 96 4c 6d 05 06 07 08 00 01 00 01 01 66 00 01 e1 12 01 90 18 04 05 06 07 08 58 02 00 00 14 14
00 00 27 11 00 00 27 12 00 00 27 13 00 00 27 14 00 00 27 15 00 00 27 16 00 00 27 17 00 00 27 18
00 00 27 19 00 00 27 1a 00 00 27 1b 00 00 27 1c 00 00 27 1d 00 00 27 1e 00 00 27 1f 00 00 27 20
00 00 27 21 00 00 27 22 00 00 27 23 00 00 27 24 00 00 27 25 00 00 27 26 00 00 27 27 00 00 27 28
00 00 27 29 00 00 27 2a 00 00 27 2b 00 00 27 2c 00 00 27 2d 00 00 27 2e 00 00 27 2f 00 00 27 30
00 00 27 31 00 00 27 32 00 00 27 33 00 00 27 34 00 00 27 35 00 00 27 36 00 00 27 37 00 00 27 38
00 00 27 39 00 00 27 3a 00 00 27 3b 00 00 27 3c 00 00 27 3d 00 00 27 3e 00 00 27 3f 00 00 27 40
00 00 27 41 00 00 27 42 00 00 27 43 00 00 27 44 00 00 27 45 00 00 27 46 00 00 27 47 00 00 27 48
00 00 27 49 00 00 27 4a 00 00 27 4b 00 00 27 4c 00 00 27 4d 00 00 27 4e 00 00 27 4f 00 00 27 50
00 00 27 51 00 00 27 52 00 00 27 53 00 00 27 54 00 00 27 55 00 00 27 56 00 00 27 57 00 00 27 58
00 00 27 59 00 00 27 5a 00 00 27 5b 00 00 27 5c 00 00 27 5d 00 00 27 5e 00 00 27 5f 00 00 27 60
00 00 27 61 00 00 27 62 00 00 27 63 00 00 27 64 00 00 27 65 00 00 27 66 00 00 27 67 00 00 27 68
00 00 27 69 00 00 27 6a 00 00 27 6b 00 00 27 6c 00 00 27 6d 00 00 27 6e 00 00 27 6f 00 00 27 70
00 00 27 71 00 00 27 72 00 00 27 73 00 00 27 74 00 00 27 75 00 00 27 76 00 00 27 77 00 00 27 78
00 00 27 79 00 00 27 7a 00 00 27 7b 00 00 27 7c 00 00 27 7d 00 00 27 7e 00 00 27 7f 00 00 27 80
00 00 27 81 00 00 27 82 00 00 27 83 00 00 27 84 00 00 4e 3b 55 69 aa 96 4c 6d 05 06 07 08 00 01
00 01 00 66 00 00 6f 12 27 85 00 00 27 86 00 00 27 87 00 00 27 88 00 00 27 89 00 00 27 8a 00 00
27 8b 00 00 27 8c 00 00 27 8d 00 00 27 8e 00 00 27 8f 00 00 27 90 00 00 27 91 00 00 27 92 00 00
27 93 00 00 27 94 00 00 27 95 00 00 27 96 00 00 27 97 00 00 27 98 00 00 27 99 00 00 27 9a 00 00
27 9b 00 00 27 9c 00 00 27 9d 00 00 27 9e 00 00 27 9f 00 00 27 a0 61 c2 55 69"""

        const val SECRET_LONG_TEXT = """
aa 96 4c 6d 05 06 07 08 00 01 00 01 81 66 00 01 f1 12 d2 09 76 04 73 2f 2a f9 c6 3f f1 57 ab a0
0e cf ac e0 43 21 bb 61 cc 66 4d 01 b5 5f 90 ae 67 6c 58 8d 05 84 6f f7 40 b7 20 fb 25 d3 3a cc
c4 8a 06 e4 fe e8 22 09 ca a3 b8 09 4c 44 0b 21 38 4c 9f 86 5e 3c 75 65 da 2a 24 94 66 43 f0 71
34 f7 43 af 75 5c 4c 00 04 88 4b 7d fd 1e f8 75 5f e7 5f 86 89 ec bf d4 f1 2e 2d 64 96 bd 5c 49
a8 3e 41 64 28 82 48 ac 97 37 2c 48 32 10 b3 80 bb ea 67 c4 51 91 5f af 19 02 00 b0 38 b3 b7 8b
55 90 47 fa d0 ce 96 00 19 dc 9b 12 ad e8 32 2b 13 1e a2 e7 71 3f 5a b7 c4 b5 dc 8d ea bc 59 cb
07 9c cc 58 87 57 88 0d ca c6 82 fe 38 dd b7 3a ab 6a 29 b2 99 a5 2c 7c 33 58 fd 3c da 54 1c 85
99 21 a7 41 44 9a a0 7a 14 1e fb 21 22 eb a9 ec 56 89 89 cb df 84 04 bc 06 cd 32 f1 6b ba e6 73
67 76 21 a9 40 53 38 de 8b ef 24 e2 a1 6a a7 64 36 92 aa 21 db 03 26 5b 23 ba c6 79 c2 96 ad 00
2f 40 6b 81 bd ec ac 5e 74 a6 c6 21 cf 3c 4f c5 8f 2d c0 f7 4b 66 96 4f b0 3b f2 9b e6 0c 19 1b
d3 7e e3 fc c4 83 3d b7 b7 46 23 a7 7d d8 e4 51 8d 30 58 4f 58 e2 b6 13 e2 b7 98 20 42 54 d9 e5
69 58 19 b1 74 ff 73 49 bc bc ad 7d 1e fc d5 7f d7 06 40 42 5b 59 74 57 7c ce 10 2b 79 73 fb 3b
99 5a db 11 aa 02 e3 fc b4 43 22 f2 f8 e9 d4 25 7e 85 64 ff 24 91 64 d4 f6 44 e3 3e d5 93 56 0b
74 0e 87 97 64 63 9e 3f 14 34 3a 36 70 8f 7e b4 88 9f 35 f2 1a a7 db 82 50 52 f9 16 94 31 51 e0
c2 77 79 cc 24 6e 92 ae 3c 79 d3 51 ba 93 27 d7 c7 42 01 c9 dd 7b 3c 82 9b 58 76 05 0d ff 6c 64
4d d4 70 43 e1 8f 42 84 ee 18 b0 01 cc e0 96 81 a8 2e e3 c9 1a 65 2a f7 de 89 d5 fa c2 5e 22 2b
f9 0e 69 5e 55 69 aa 96 4c 6d 05 06 07 08 00 01 00 01 80 66 00 00 71 12 60 ed 91 5a fe 06 f3 ef
ff db 50 99 5b 81 04 e8 bd 44 7a b9 19 0b 60 c4 f8 f6 36 de 6a ea d7 32 6d 57 37 85 da 3c 5a 37
97 ae cf 2b d9 52 6a f9 36 27 80 62 68 51 3a b8 f5 db fb 50 1b de d4 c9 5d 61 1a 5b b2 47 0e 64
ed ff 39 22 90 38 03 5a 7d 6a fa 3e 74 5e 7a a7 b6 0a 10 e8 b2 38 ea 93 40 95 f8 84 ac 77 17 5f
50 3f a9 ef 67 27 f9 4b a8 31 55 69"""

        const val PLAIN_LONG_NO_SPLIT = """
aa 96 4c 6d 05 06 07 08 00 01 00 01 00 66 00 02 4f 12 01 90 18 04 05 06 07 08 58 02 00 00 14 14
00 00 27 11 00 00 27 12 00 00 27 13 00 00 27 14 00 00 27 15 00 00 27 16 00 00 27 17 00 00 27 18
00 00 27 19 00 00 27 1a 00 00 27 1b 00 00 27 1c 00 00 27 1d 00 00 27 1e 00 00 27 1f 00 00 27 20
00 00 27 21 00 00 27 22 00 00 27 23 00 00 27 24 00 00 27 25 00 00 27 26 00 00 27 27 00 00 27 28
00 00 27 29 00 00 27 2a 00 00 27 2b 00 00 27 2c 00 00 27 2d 00 00 27 2e 00 00 27 2f 00 00 27 30
00 00 27 31 00 00 27 32 00 00 27 33 00 00 27 34 00 00 27 35 00 00 27 36 00 00 27 37 00 00 27 38
00 00 27 39 00 00 27 3a 00 00 27 3b 00 00 27 3c 00 00 27 3d 00 00 27 3e 00 00 27 3f 00 00 27 40
00 00 27 41 00 00 27 42 00 00 27 43 00 00 27 44 00 00 27 45 00 00 27 46 00 00 27 47 00 00 27 48
00 00 27 49 00 00 27 4a 00 00 27 4b 00 00 27 4c 00 00 27 4d 00 00 27 4e 00 00 27 4f 00 00 27 50
00 00 27 51 00 00 27 52 00 00 27 53 00 00 27 54 00 00 27 55 00 00 27 56 00 00 27 57 00 00 27 58
00 00 27 59 00 00 27 5a 00 00 27 5b 00 00 27 5c 00 00 27 5d 00 00 27 5e 00 00 27 5f 00 00 27 60
00 00 27 61 00 00 27 62 00 00 27 63 00 00 27 64 00 00 27 65 00 00 27 66 00 00 27 67 00 00 27 68
00 00 27 69 00 00 27 6a 00 00 27 6b 00 00 27 6c 00 00 27 6d 00 00 27 6e 00 00 27 6f 00 00 27 70
00 00 27 71 00 00 27 72 00 00 27 73 00 00 27 74 00 00 27 75 00 00 27 76 00 00 27 77 00 00 27 78
00 00 27 79 00 00 27 7a 00 00 27 7b 00 00 27 7c 00 00 27 7d 00 00 27 7e 00 00 27 7f 00 00 27 80
00 00 27 81 00 00 27 82 00 00 27 83 00 00 27 84 00 00 27 85 00 00 27 86 00 00 27 87 00 00 27 88
00 00 27 89 00 00 27 8a 00 00 27 8b 00 00 27 8c 00 00 27 8d 00 00 27 8e 00 00 27 8f 00 00 27 90
00 00 27 91 00 00 27 92 00 00 27 93 00 00 27 94 00 00 27 95 00 00 27 96 00 00 27 97 00 00 27 98
00 00 27 99 00 00 27 9a 00 00 27 9b 00 00 27 9c 00 00 27 9d 00 00 27 9e 00 00 27 9f 00 00 27 a0
11 ba 55 69"""

        const val SECRET_LONG_NO_SPLIT = """
aa 96 4c 6d 05 06 07 08 00 01 00 01 80 66 00 02 51 12 d2 09 76 04 73 2f 2a f9 c6 3f f1 57 ab a0
0e cf ac e0 43 21 bb 61 cc 66 4d 01 b5 5f 90 ae 67 6c 58 8d 05 84 6f f7 40 b7 20 fb 25 d3 3a cc
c4 8a 06 e4 fe e8 22 09 ca a3 b8 09 4c 44 0b 21 38 4c 9f 86 5e 3c 75 65 da 2a 24 94 66 43 f0 71
34 f7 43 af 75 5c 4c 00 04 88 4b 7d fd 1e f8 75 5f e7 5f 86 89 ec bf d4 f1 2e 2d 64 96 bd 5c 49
a8 3e 41 64 28 82 48 ac 97 37 2c 48 32 10 b3 80 bb ea 67 c4 51 91 5f af 19 02 00 b0 38 b3 b7 8b
55 90 47 fa d0 ce 96 00 19 dc 9b 12 ad e8 32 2b 13 1e a2 e7 71 3f 5a b7 c4 b5 dc 8d ea bc 59 cb
07 9c cc 58 87 57 88 0d ca c6 82 fe 38 dd b7 3a ab 6a 29 b2 99 a5 2c 7c 33 58 fd 3c da 54 1c 85
99 21 a7 41 44 9a a0 7a 14 1e fb 21 22 eb a9 ec 56 89 89 cb df 84 04 bc 06 cd 32 f1 6b ba e6 73
67 76 21 a9 40 53 38 de 8b ef 24 e2 a1 6a a7 64 36 92 aa 21 db 03 26 5b 23 ba c6 79 c2 96 ad 00
2f 40 6b 81 bd ec ac 5e 74 a6 c6 21 cf 3c 4f c5 8f 2d c0 f7 4b 66 96 4f b0 3b f2 9b e6 0c 19 1b
d3 7e e3 fc c4 83 3d b7 b7 46 23 a7 7d d8 e4 51 8d 30 58 4f 58 e2 b6 13 e2 b7 98 20 42 54 d9 e5
69 58 19 b1 74 ff 73 49 bc bc ad 7d 1e fc d5 7f d7 06 40 42 5b 59 74 57 7c ce 10 2b 79 73 fb 3b
99 5a db 11 aa 02 e3 fc b4 43 22 f2 f8 e9 d4 25 7e 85 64 ff 24 91 64 d4 f6 44 e3 3e d5 93 56 0b
74 0e 87 97 64 63 9e 3f 14 34 3a 36 70 8f 7e b4 88 9f 35 f2 1a a7 db 82 50 52 f9 16 94 31 51 e0
c2 77 79 cc 24 6e 92 ae 3c 79 d3 51 ba 93 27 d7 c7 42 01 c9 dd 7b 3c 82 9b 58 76 05 0d ff 6c 64
4d d4 70 43 e1 8f 42 84 ee 18 b0 01 cc e0 96 81 a8 2e 60 ed 91 5a fe 06 f3 ef ff db 50 99 5b 81
04 e8 bd 44 7a b9 19 0b 60 c4 f8 f6 36 de 6a ea d7 32 6d 57 37 85 da 3c 5a 37 97 ae cf 2b d9 52
6a f9 36 27 80 62 68 51 3a b8 f5 db fb 50 1b de d4 c9 5d 61 1a 5b b2 47 0e 64 ed ff 39 22 90 38
03 5a 7d 6a fa 3e 74 5e 7a a7 b6 0a 10 e8 b2 38 ea 93 40 95 f8 84 ac 77 17 5f 50 3f a9 ef 67 27
f9 4b 61 7f 55 69"""
    }
}